
package com.bangcommunity.bbframe.sdm.web.shiro.filter;

import com.bangcommunity.bbframe.common.base.BaseResult;
import com.bangcommunity.bbframe.common.base.MainConfigLoader;
import com.bangcommunity.bbframe.common.base.ResultCode;
import com.bangcommunity.bbframe.common.utils.lang.StringUtils;
import com.bangcommunity.bbframe.sdm.utils.JacksonUtil;
import com.bangcommunity.bbframe.sdm.utils.RequestUtils;
import com.bangcommunity.bbframe.sdm.web.exception.RestConf;
import com.bangcommunity.bbframe.sdm.web.shiro.SsoConfig;
import com.bangcommunity.bbframe.sdm.web.shiro.realm.IShiroUser;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Serializable;
import java.net.URLEncoder;

/**
 * 基于Shiro 登陆认证的Filter
 *
 * @version 1.0
 * @author tanghc
 */
public abstract class AbstractSdmSsoRedirectAuthenticationFilter<PK extends Serializable, TK extends AuthenticationToken>
        extends AbstractSdmTokenAuthenticationFilter<PK, TK> {

    @Autowired(required = false)
    private SsoConfig ssoConfig;

    @Override
    protected void redirectToLogin(ServletRequest request, ServletResponse response) throws IOException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String queryString = StringUtils.trimToEmpty(httpServletRequest.getQueryString());
        String callbackUrl = ssoConfig.getLocalHost() + httpServletRequest.getRequestURI()
                + (StringUtils.isNotBlank(queryString) ? "?" + queryString : "");

        String redirectUrl = ssoConfig.getSsoHost() + "/login?url=" + URLEncoder.encode(callbackUrl, "UTF-8")
                + "&productCode=" + MainConfigLoader.getInstance().getProductCode() + "&appCode="
                + MainConfigLoader.getInstance().getAppCode();
        WebUtils.issueRedirect(request, response, redirectUrl);
    }

    @Override
    protected void onNotLogin(HttpServletRequest request, HttpServletResponse response) {
        try {
            boolean ajaxRequest = RequestUtils.isAjaxRequest(request);
            if (ajaxRequest || RestConf.isRest) {
                BaseResult result = BaseResult.fail(ResultCode.NOTLOGIN.getCode(), "登录信息有误");
                HttpServletResponse res = response;
                res.setHeader("Content-Type", "application/json;charset=utf-8");
                PrintWriter out = res.getWriter();
                JacksonUtil jsonMapper = new JacksonUtil();
                out.write(jsonMapper.toJson(result));
                out.flush();
                out.close();
            } else {
                redirectToLogin(request, response);
            }
        } catch (IOException e) {
            logger.error("onNotLogin response exceptioon: {}", e);
        }
    }

    @Override
    protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
            ServletResponse response) throws Exception {
        boolean b = super.onLoginSuccess(token, subject, request, response);
        if (null != subject) {
            IShiroUser<PK> shiroUser = (IShiroUser<PK>) subject.getPrincipal();
            if (null != shiroUser && StringUtils.isNotBlank(shiroUser.getToken())) {
                Cookie cookie = new Cookie(RestConf.tokenKey, shiroUser.getToken());
                cookie.setPath("/");
                ((HttpServletResponse) response).addCookie(cookie);
                ((HttpServletResponse) response).addHeader(RestConf.tokenKey, shiroUser.getToken());
            }
        }
        return b;
    }
}
